

#ifndef __STL_TYPE__H__
#define __STL_TYPE__H__


// 这个文件只定义类型，常量，及常用的宏定义

#ifndef NULL
#define NULL 0
#endif



typedef unsigned char unt8;
typedef unsigned short unt16;
typedef unsigned int unt32;

typedef signed char nt8;
typedef signed short nt16;
typedef signed int nt32;

#define unt8_MAX_number  255 
#define unt16_MAX_number 65535 
#define unt32_MAX_number 4294967295UL 

#define nt8_MAX_number  127  
#define nt16_MAX_number 32767  
#define nt32_MAX_number 2147483647L 

#define nt8_MIN_number  -127 
#define nt16_MIN_number -32767 
#define nt32_MIN_number -2147483647L 



//float型只能保证6位有效数字，double可以保证15位有效数字。
//因为单精度只能保证6位有效数字。所以Epsilon最小是0.00001f。如果再小，对一些数学计算，就可能出错。

//当用于图像处理，神经网络，3D渲染，游戏引擎等对小数点精度要求不高的计算时，用单精度的精度够用了。
//当用于科学计算时，比如微分方程的数值计算，应使用双精度的浮点数据，以提高计算精度。

// 矩阵计算最好用双精度。矩阵大量乘法求和会引入大量的误差，双精度下的 Epsilon 远远大于 精度极限，矩阵计算迭代收敛才不至于陷入死循环。

#define PRECISION 1

#if (PRECISION == 1)  //real（实数）定义为单精度类型

typedef float real_t; // _t表示数据类型。 
//#define real_t float 
#define Epsilon    0.00001f  //定义无穷小量（绝对值无穷小）。再小的话矩阵特征值，奇异值分解就出问题了
#define Epsilon_e2 0.000000000001f  //定义无穷小量的平方（绝对值无穷小）。再小的话矩阵特征值，奇异值分解就出问题了

#define  PI_mul_2  6.283186f   //PI的double宏定义 (6.283185307……) ，这里稍微设大一点点
#define  PI		   3.141593f   //PI的double宏定义
#define  PI_div_2  1.570796f   //PI/2的double宏定义
#define  PI_div_3  1.047198f   //PI/3的double宏定义
#define  PI_div_4  0.785398f   //PI/4的double宏定义
#define  EulerNumber   2.718282f   //自然对数底数e的宏定义。e又叫欧拉数，以数学家欧拉的名字命名。


#elif(PRECISION == 2) //real（实数）定义为双精度类型
//#define real_t double 

typedef double real_t;
//#define Epsilon        0.000001 //定义无穷小量（绝对值无穷小）。
//#define Epsilon_e2     0.000000000001  //定义无穷小量的平方（绝对值无穷小）。再小的话矩阵特征值，奇异值分解就出问题了
#define Epsilon        0.0000000001 //定义无穷小量（绝对值无穷小）。
#define Epsilon_e2     0.00000000000000000001  //定义无穷小量的平方（绝对值无穷小）。再小的话矩阵特征值，奇异值分解就出问题了
#define  PI_mul_2      6.2831853071795865   //PI的double宏定义 (6.283185307……) ，这里稍微设大一点点
#define  PI            3.1415926535897931   //PI的double宏定义
#define  PI_div_2      1.5707963267948966   //PI/2的double宏定义
#define  PI_div_3      1.0471975511965977   //PI/3的double宏定义
#define  PI_div_4	   0.7853981633974483   //PI/4的double宏定义
#define  EulerNumber   2.7182818284590451   //自然对数底数e的宏定义。e又叫欧拉数，以数学家欧拉的名字命名。

#endif


//四舍五入宏定义,d可以是单精度或双精度的。
#define Round(d) (int)(((d)>0)?((d)+0.5f):((d)-0.5f))
//向上取整
#define Ceil(d)  (int)(((d)>0)?(((d)-(int)(d))==0?(d):((d)+1)):(d))
//向下取整
#define Floor(d)  (int)(((d)>0)?(d):(((d)-(int)(d))==0?(d):((d)-1)))
//计算最大值
#define Max(a,b)            (((a) > (b)) ? (a) : (b))
//计算最小值
#define Min(a,b)            (((a) < (b)) ? (a) : (b))
//绝对值的宏定义
#define ABS(x) ((x)>0?(x):(-(x)))
//符号函数，正数返回1，负数返回-1
#define Sign(x)  (((x) > 0) ? (1) : (((x) < 0) ? (-1) : 0))



#ifndef __cplusplus
typedef unsigned char bool;
#define	true	1
#define	false	0

#endif

//#include <stdint.h>


typedef void* Datapointer;  // 数据指针，可以指向任意类型的数据

/// <summary>
/// offset_of(struct_type, mem_name)：计算结构体struct_type里的元素mem_name相对结构体的偏移地址。
/// 原理：0被强制转换为struct_type的指针类型，这个struct_type的地址是0，mem_name的地址就是相对0的偏移地址，也是相对结构体的偏移地址。
/// </summary>
#define offset_of(struct_type, mem_name)  (char *)(&(((struct_type*)0)->mem_name))

/// <summary>
/// container_of：计算包含节点指针Node_ptr的结构体指针。结构体类型名为struct_type，节点在结构体内的元素名称是node_in_struct。
/// 在C语言的数据结构中用得到。   
/// </summary>
#define container_of(Node_ptr, struct_type, nodename_in_struct) (struct_type *)((char *)(Node_ptr) - offset_of(struct_type,nodename_in_struct) )


typedef int (CompareFuncPoint)(void*, void*); // 对比函数指针宏定义









#include"stl_print.h"  // 打印函数用的最多


#endif // !__STL_TYPE__H__








